package top.bugger168.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.bugger168.base.exception.CourseOnlineException;
import top.bugger168.content.mapper.TeachplanMapper;
import top.bugger168.content.mapper.TeachplanMediaMapper;
import top.bugger168.content.model.dto.BindTeachplanMediaDto;
import top.bugger168.content.model.dto.SaveTeachplanDto;
import top.bugger168.content.model.dto.TeachplanDto;
import top.bugger168.content.model.po.Teachplan;
import top.bugger168.content.model.po.TeachplanMedia;
import top.bugger168.content.service.TeachplanService;

import java.time.LocalDateTime;
import java.util.List;

/**
 *  课程计划service接口实现类
 */
@Service
public class TeachplanServiceImpl implements TeachplanService {
    @Autowired
    TeachplanMapper teachplanMapper;
    @Autowired
    TeachplanMediaMapper teachplanMediaMapper;

    @Override
    public List<TeachplanDto> findTeachplanTree(long courseId) {
        return teachplanMapper.selectTreeNodes(courseId);
    }

    @Transactional
    @Override
    public void saveTeachplan(SaveTeachplanDto teachplanDto) {
        //课程计划id
        Long id = teachplanDto.getId();
        if(id!=null){
            // 修改课程计划
            Teachplan teachplan = teachplanMapper.selectById(id);
            BeanUtils.copyProperties(teachplanDto,teachplan);
            teachplanMapper.updateById(teachplan);
        }else{
            // 添加课程计划
            // 取出同父同级别的课程计划数量
            int count = getTeachplanCount(teachplanDto.getCourseId(), teachplanDto.getParentid());
            Teachplan teachplanNew = new Teachplan();
            //设置排序号
            teachplanNew.setOrderby(count+1);
            BeanUtils.copyProperties(teachplanDto,teachplanNew);

            teachplanMapper.insert(teachplanNew);
        }
    }

    @Transactional
    @Override
    public void removeTeachplan(long teachplanId) {
        // 判断删除的是大章节还是小章节,大章节删除要判断下属没有小章节,小章节要删除要保证连带删除媒体
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if(teachplan.getGrade()==1){
            // 大章节删除逻辑,查表第二章节中当前章节的子章节数,如果为0则可以删除,删除的话要更新后面的章节排序
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getParentid,teachplanId);
            int count = teachplanMapper.selectCount(queryWrapper);

            if(count>0){
                // TODO: 2023/4/13 这里要携带错误代码120409尚未实现
                CourseOnlineException.cast("课程计划信息还有子级信息,无法操作");
            }else{
                // 删除大章节,更新排序表
                teachplanMapper.deleteById(teachplanId);
                resort(teachplan.getOrderby(),teachplan.getCourseId(),teachplan.getParentid());
            }
        }else if(teachplan.getGrade()==2){
            // 小章节删除逻辑,查媒介表,将媒介表中的内容同步删除后,删除当前小章节,刷新其他小章节排序
            LambdaQueryWrapper<TeachplanMedia> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(TeachplanMedia::getCourseId,teachplan.getCourseId()).eq(TeachplanMedia::getTeachplanId,teachplanId);
            teachplanMediaMapper.delete(queryWrapper);
            teachplanMapper.deleteById(teachplanId);
            resort(teachplan.getOrderby(),teachplan.getCourseId(),teachplan.getParentid());
        }
    }

    @Transactional
    @Override
    public void moveupTeachplan(long teachplanId) {
        // order为1的话忽略,否则和上一个交换
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if(teachplan.getOrderby()==1) return;
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Teachplan::getCourseId,teachplan.getCourseId())
                .eq(Teachplan::getParentid,teachplan.getParentid())
                .eq(Teachplan::getOrderby,teachplan.getOrderby()-1);
        Teachplan upItem = teachplanMapper.selectOne(queryWrapper);
        // 交换order值
        teachplan.setOrderby(teachplan.getOrderby()-1);
        upItem.setOrderby(upItem.getOrderby()+1);
        teachplanMapper.updateById(teachplan);
        teachplanMapper.updateById(upItem);
    }

    @Transactional
    @Override
    public void movedownTeachplan(long teachplanId) {
        // order为最后一个的话忽略,否则和下一个交换
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        int count = getTeachplanCount(teachplan.getCourseId(),teachplan.getParentid());
        if(teachplan.getOrderby()==count) return;
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Teachplan::getCourseId,teachplan.getCourseId())
                .eq(Teachplan::getParentid,teachplan.getParentid())
                .eq(Teachplan::getOrderby,teachplan.getOrderby()+1);
        Teachplan nextItem = teachplanMapper.selectOne(queryWrapper);
        // 交换order值
        teachplan.setOrderby(teachplan.getOrderby()+1);
        nextItem.setOrderby(nextItem.getOrderby()-1);
        teachplanMapper.updateById(teachplan);
        teachplanMapper.updateById(nextItem);
    }

    @Transactional
    @Override
    public TeachplanMedia associationMedia(BindTeachplanMediaDto bindTeachplanMediaDto) {
        //教学计划id
        Long teachplanId = bindTeachplanMediaDto.getTeachplanId();
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if(teachplan==null){
            CourseOnlineException.cast("教学计划不存在");
        }
        Integer grade = teachplan.getGrade();
        if(grade!=2){
            CourseOnlineException.cast("只允许第二级教学计划绑定媒资文件");
        }
        //课程id
        Long courseId = teachplan.getCourseId();

        //先删除原来该教学计划绑定的媒资
        teachplanMediaMapper.delete(new LambdaQueryWrapper<TeachplanMedia>().eq(TeachplanMedia::getTeachplanId,teachplanId));

        //再添加教学计划与媒资的绑定关系
        TeachplanMedia teachplanMedia = new TeachplanMedia();
        teachplanMedia.setCourseId(courseId);
        teachplanMedia.setTeachplanId(teachplanId);
        teachplanMedia.setMediaFilename(bindTeachplanMediaDto.getFileName());
        teachplanMedia.setMediaId(bindTeachplanMediaDto.getMediaId());
        teachplanMedia.setCreateDate(LocalDateTime.now());
        teachplanMediaMapper.insert(teachplanMedia);
        return teachplanMedia;
    }

    @Transactional
    @Override
    public void cutMedia(long teachplanId, String mediaId) {
        // 目前由于前端传的参数没有teachplanId,只有mediaId,删除会导致其他课程计划的相同媒资被删除
        // 等以后前端参数解决了再修改
        teachplanMediaMapper.delete(new LambdaQueryWrapper<TeachplanMedia>().eq(TeachplanMedia::getMediaId,mediaId));
    }

    /**
     *  获取最新的排序号
     * @param courseId  课程id
     * @param parentId  父课程计划id
     * @return int 最新排序号
     */
    private int getTeachplanCount(long courseId,long parentId){
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Teachplan::getCourseId,courseId);
        queryWrapper.eq(Teachplan::getParentid,parentId);
        return teachplanMapper.selectCount(queryWrapper);
    }

    /**
     * 传入当前章节的排序,删除当前章节后,将大于当前排序的自减
     * @param orderby
     * @param courseId
     * @param parentId
     */
    private void resort(int orderby,long courseId,long parentId){
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Teachplan::getCourseId,courseId).eq(Teachplan::getParentid,parentId).gt(Teachplan::getOrderby,orderby);
        List<Teachplan> teachplans = teachplanMapper.selectList(queryWrapper);
        for (Teachplan teachplan : teachplans) {
            teachplan.setOrderby(teachplan.getOrderby()-1);
            teachplanMapper.updateById(teachplan);
        }
    }
}